#include "orderservice.h"
#include "shoppingcart.h"
#include "orderdao.h"
#include "productdao.h"
#include "inventorydao.h"
#include "appinitializer.h"
#include <QDebug>
#include <QDateTime>

OrderService::OrderService(QObject *parent)
    : QObject(parent),
      m_orderDAO(nullptr),
      m_productDAO(nullptr),
      m_inventoryDAO(nullptr)
{
}

void OrderService::setOrderDAO(OrderDAO *orderDAO)
{
    m_orderDAO = orderDAO;
}

void OrderService::setProductDAO(ProductDAO *productDAO)
{
    m_productDAO = productDAO;
}

void OrderService::setInventoryDAO(InventoryDAO *inventoryDAO)
{
    m_inventoryDAO = inventoryDAO;
}

int OrderService::createOrderFromCart(const ShoppingCart &cart, int userId, int customerId,
                                    PaymentMethod paymentMethod)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return -1;
    }

    if (cart.isEmpty()) {
        emit errorOccurred("购物车为空，无法创建订单");
        return -1;
    }

    // 计算金额
    double totalAmount = cart.calculateSubtotal();
    double discountAmount = cart.getDiscountAmount();
    double finalAmount = cart.getTotal();

    // 创建订单对象
    Order order(userId, customerId, totalAmount, discountAmount, finalAmount, paymentMethod);

    // 添加订单详情
    QVector<CartItem> items = cart.getItems();
    for (const CartItem &item : items) {
        order.addOrderDetail(item.productId, item.quantity, item.price,
                           item.subtotal, item.allowDiscount);
    }

    // 验证库存
    if (!validateInventory(order)) {
        emit errorOccurred("库存不足，无法创建订单");
        return -1;
    }

    // 保存订单到数据库
    int orderId = m_orderDAO->createOrder(order);
    if (orderId <= 0) {
        emit errorOccurred("创建订单失败");
        return -1;
    }

    // 更新库存
    if (!updateInventoryForOrder(order)) {
        // 库存更新失败，删除订单
        m_orderDAO->deleteOrder(orderId);
        emit errorOccurred("库存更新失败，订单已取消");
        return -1;
    }

    // 设置订单号
    order.setOrderId(orderId);

    emit orderCreated(orderId);
    return orderId;
}

bool OrderService::payOrder(int orderId, PaymentMethod paymentMethod, const QString &transactionNo)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return false;
    }

    // 验证订单是否可以支付
    if (!canOrderBePaid(orderId)) {
        emit errorOccurred("订单无法支付");
        return false;
    }

    // 更新订单支付信息
    QDateTime paymentTime = QDateTime::currentDateTime();
    if (!m_orderDAO->updateOrderPayment(orderId, transactionNo, paymentTime)) {
        emit errorOccurred("更新订单支付信息失败");
        return false;
    }

    // 获取订单详情
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        emit errorOccurred("获取订单详情失败");
        return false;
    }

    // 更新销售统计
    if (!updateSalesStatistics(order)) {
        // 这里可以选择记录日志但不中断支付流程
        qWarning() << "更新销售统计失败，订单ID:" << orderId;
    }

    emit orderPaid(orderId);
    return true;
}

bool OrderService::cancelOrder(int orderId, const QString &reason)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return false;
    }

    // 验证订单是否可以取消
    if (!canOrderBeCancelled(orderId)) {
        emit errorOccurred("订单无法取消");
        return false;
    }

    // 获取订单详情
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        emit errorOccurred("订单不存在");
        return false;
    }

    // 恢复库存
    if (!restoreInventoryForOrder(order)) {
        emit errorOccurred("恢复库存失败");
        return false;
    }

    // 更新订单状态为已取消
    if (!m_orderDAO->updateOrderStatus(orderId, ORDER_CANCELLED)) {
        emit errorOccurred("更新订单状态失败");
        return false;
    }

    // 记录取消原因到日志（这里简化处理，实际应该记录到日志表）
    qDebug() << "订单取消:" << orderId << "原因:" << reason;

    emit orderCancelled(orderId);
    return true;
}

bool OrderService::completeOrder(int orderId)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return false;
    }

    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        emit errorOccurred("订单不存在");
        return false;
    }

    // 只有已支付的订单才能完成
    if (order.getStatus() != ORDER_PAID) {
        emit errorOccurred("只有已支付的订单才能完成");
        return false;
    }

    // 更新订单状态为已完成
    if (!m_orderDAO->updateOrderStatus(orderId, ORDER_COMPLETED)) {
        emit errorOccurred("更新订单状态失败");
        return false;
    }

    emit orderCompleted(orderId);
    return true;
}

bool OrderService::refundOrder(int orderId, const QString &reason)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return false;
    }

    // 验证订单是否可以退款
    if (!canOrderBeRefunded(orderId)) {
        emit errorOccurred("订单无法退款");
        return false;
    }

    // 获取订单详情
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        emit errorOccurred("订单不存在");
        return false;
    }

    // 恢复库存
    if (!restoreInventoryForOrder(order)) {
        emit errorOccurred("恢复库存失败");
        return false;
    }

    // 更新订单状态为已退款
    if (!m_orderDAO->updateOrderStatus(orderId, ORDER_REFUNDED)) {
        emit errorOccurred("更新订单状态失败");
        return false;
    }

    // 记录退款原因到日志（这里简化处理，实际应该记录到日志表）
    qDebug() << "订单退款:" << orderId << "原因:" << reason << "金额:" << order.getFinalAmount();

    emit orderRefunded(orderId);
    return true;
}

Order OrderService::getOrderDetails(int orderId)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return Order();
    }

    return m_orderDAO->getOrderById(orderId);
}

QVector<Order> OrderService::getUserOrders(int userId)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return QVector<Order>();
    }

    return m_orderDAO->getOrdersByUserId(userId);
}

QVector<Order> OrderService::getCustomerOrders(int customerId)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return QVector<Order>();
    }

    return m_orderDAO->getOrdersByCustomerId(customerId);
}

QVector<Order> OrderService::getOrdersByDateRange(const QDateTime &startDate, const QDateTime &endDate)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return QVector<Order>();
    }

    return m_orderDAO->getOrdersByDateRange(startDate, endDate);
}

QMap<QString, QVariant> OrderService::getTodayOrderStats()
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return QMap<QString, QVariant>();
    }

    QMap<QString, QVariant> stats;
    stats["order_count"] = m_orderDAO->getTodayOrderCount();
    stats["sales_total"] = m_orderDAO->getTodaySales();

    return stats;
}

QMap<QString, QVariant> OrderService::getSalesStats(const QDateTime &startDate, const QDateTime &endDate)
{
    if (!m_orderDAO) {
        emit errorOccurred("订单DAO未设置");
        return QMap<QString, QVariant>();
    }

    QMap<QString, double> salesStats = m_orderDAO->getSalesStatistics(startDate, endDate);
    QMap<QString, QVariant> result;

    for (auto it = salesStats.begin(); it != salesStats.end(); ++it) {
        result[it.key()] = it.value();
    }

    return result;
}

QString OrderService::generateOrderNumber()
{
    QDateTime now = QDateTime::currentDateTime();
    QString dateStr = now.toString("yyyyMMdd");

    // 获取今日订单数量
    int todayOrderCount = m_orderDAO ? m_orderDAO->getTodayOrderCount() : 0;

    // 生成订单号：日期 + 4位序列号
    QString sequence = QString("%1").arg(todayOrderCount + 1, 4, 10, QChar('0'));
    return dateStr + sequence;
}

bool OrderService::canOrderBePaid(int orderId)
{
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        return false;
    }

    // 只有待支付的订单可以支付
    return order.getStatus() == ORDER_PENDING;
}

bool OrderService::canOrderBeCancelled(int orderId)
{
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        return false;
    }

    // 待支付和已支付的订单可以取消
    return order.getStatus() == ORDER_PENDING || order.getStatus() == ORDER_PAID;
}

bool OrderService::canOrderBeRefunded(int orderId)
{
    Order order = m_orderDAO->getOrderById(orderId);
    if (order.getOrderId() <= 0) {
        return false;
    }

    // 已支付的订单可以退款
    return order.getStatus() == ORDER_PAID;
}

/**
 * 订单库存扣减算法
 * 业务逻辑：订单支付成功后，扣减相应商品的库存数量
 * 扣减流程：
 * 1. 遍历订单中的所有商品详情
 * 2. 对每个商品执行库存扣减操作
 * 3. 如果任何商品扣减失败，整个操作失败
 * 注意：此操作应在事务中执行，确保数据一致性
 * 
 * @param order 已支付的订单对象
 * @return 库存扣减是否成功
 */
bool OrderService::updateInventoryForOrder(const Order &order)
{
    if (!m_inventoryDAO) {
        emit errorOccurred("库存DAO未设置");
        return false;
    }

    QVector<OrderDetail> details = order.getOrderDetails();
    for (const OrderDetail &detail : details) {
        // 减少商品库存
        if (!m_inventoryDAO->decreaseStock(detail.productId, detail.quantity)) {
            return false;
        }
    }

    return true;
}

/**
 * 订单库存恢复算法
 * 业务逻辑：订单取消或退款时，恢复相应商品的库存数量
 * 恢复流程：
 * 1. 遍历订单中的所有商品详情
 * 2. 对每个商品执行库存增加操作
 * 3. 如果任何商品恢复失败，整个操作失败
 * 应用场景：订单取消、订单退款等逆向操作
 * 
 * @param order 需要恢复库存的订单对象
 * @return 库存恢复是否成功
 */
bool OrderService::restoreInventoryForOrder(const Order &order)
{
    if (!m_inventoryDAO) {
        emit errorOccurred("库存DAO未设置");
        return false;
    }

    QVector<OrderDetail> details = order.getOrderDetails();
    for (const OrderDetail &detail : details) {
        // 增加商品库存
        if (!m_inventoryDAO->increaseStock(detail.productId, detail.quantity)) {
            return false;
        }
    }

    return true;
}

/**
 * 订单库存验证算法
 * 业务逻辑：在创建订单前验证所有商品的库存是否充足
 * 验证流程：
 * 1. 遍历订单中的所有商品详情
 * 2. 查询每个商品的当前库存数量
 * 3. 比较库存数量与订单需求数量
 * 4. 如果任何商品库存不足，返回失败并提供详细错误信息
 * 
 * @param order 待验证的订单对象
 * @return 库存验证是否通过
 */
bool OrderService::validateInventory(const Order &order)
{
    if (!m_inventoryDAO) {
        emit errorOccurred("库存DAO未设置");
        return false;
    }

    QVector<OrderDetail> details = order.getOrderDetails();
    for (const OrderDetail &detail : details) {
        // 检查商品库存是否足够
        int currentStock = m_inventoryDAO->getCurrentStock(detail.productId);
        if (currentStock < detail.quantity) {
            emit errorOccurred(QString("商品ID %1 库存不足，当前库存: %2，需要: %3")
                              .arg(detail.productId)
                              .arg(currentStock)
                              .arg(detail.quantity));
            return false;
        }
    }

    return true;
}

bool OrderService::updateSalesStatistics(const Order &order)
{
    if (!m_orderDAO || !m_productDAO) {
        emit errorOccurred("订单DAO或商品DAO未设置");
        return false;
    }

    // 获取订单详情
    QVector<OrderDetail> details = order.getOrderDetails();
    QDate orderDate = order.getOrderTime().date();

    // 开始事务
    Database* db = AppInitializer::database();
    if (!db->beginTransaction()) {
        emit errorOccurred("开始事务失败");
        return false;
    }

    try {
        for (const OrderDetail &detail : details) {
            // 获取商品信息
            QMap<QString, QVariant> productInfo = m_productDAO->getProductById(detail.productId);
            if (productInfo.isEmpty()) {
                throw QString("商品不存在, ID: %1").arg(detail.productId);
            }

            double purchasePrice = productInfo["purchase_price"].toDouble();
            double salesAmount = detail.subtotal;
            double profit = salesAmount - (purchasePrice * detail.quantity);

            // 检查是否已存在该商品当天的统计记录
            QString checkQuery = "SELECT * FROM sales_stat WHERE product_id = ? AND date = ?";
            QVector<QMap<QString, QVariant>> existingStats = db->query(checkQuery,
                {detail.productId, orderDate.toString("yyyy-MM-dd")});

            if (existingStats.isEmpty()) {
                // 插入新记录
                QString insertQuery = "INSERT INTO sales_stat (product_id, date, quantity_sold, sales_amount, profit) "
                                    "VALUES (?, ?, ?, ?, ?)";
                if (!db->execute(insertQuery, {
                    detail.productId,
                    orderDate.toString("yyyy-MM-dd"),
                    detail.quantity,
                    salesAmount,
                    profit
                })) {
                    throw QString("插入销售统计失败，商品ID: %1").arg(detail.productId);
                }
            } else {
                // 更新现有记录
                QString updateQuery = "UPDATE sales_stat SET "
                                    "quantity_sold = quantity_sold + ?, "
                                    "sales_amount = sales_amount + ?, "
                                    "profit = profit + ? "
                                    "WHERE product_id = ? AND date = ?";
                if (!db->execute(updateQuery, {
                    detail.quantity,
                    salesAmount,
                    profit,
                    detail.productId,
                    orderDate.toString("yyyy-MM-dd")
                })) {
                    throw QString("更新销售统计失败，商品ID: %1").arg(detail.productId);
                }
            }
        }

        // 提交事务
        if (!db->commitTransaction()) {
            throw QString("提交事务失败");
        }

        return true;
    } catch (const QString &error) {
        // 回滚事务
        db->rollbackTransaction();
        emit errorOccurred(error);
        return false;
    }
}
